package my.suveng.chat.export.task.model.result;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import my.suveng.model.common.interfaces.response.IMessage;
import my.suveng.model.common.interfaces.response.IMessageBuilder;
import my.suveng.model.common.response.Message;
import my.suveng.model.common.response.base.CodeEnum;
import my.suveng.util.log.LogDetail;

/**
 * 公共类,可自行开发扩展 返回给调用方
 *
 * @author suwenguang
 */
@Slf4j
public class Result<T> implements IMessage<T>, IMessageBuilder {
    /**
     * 错误码
     */
    private Integer code;

    /**
     * 业务追踪id
     */
    private String requestId;

    /**
     * 标志, 业务判断
     */
    private boolean success;

    /**
     * 业务消息,系统透传,最好增加错误在后面,标识业务系统
     */
    private String message;

    /**
     * 消息数据,系统透传
     */
    private T data;

    /**
     * 构造器
     *
     * @param <E>
     *            返回类型
     *
     * @return {@link Result}
     */
    public static <E> Result<E> success() {
        return success(null);
    }

    /**
     * 构造器
     *
     * @param data
     *            返回的数据
     * @param <E>
     *            返回类型
     *
     * @return {@link Result}
     */
    public static <E> Result<E> success(E data) {
        return build(ResultCode.success, data);
    }

    /**
     * 构造器
     *
     * @param code
     *            错误码
     * @param data
     *            返回的数据
     * @param <E>
     *            返回类型
     *
     * @return {@link Result}
     */
    public static <E> Result<E> build(ResultCode code, E data) {
        return build(code, data, "");
    }

    /**
     * 构造器
     *
     * @param code
     *            错误码
     * @param data
     *            返回的数据
     * @param requestId
     *            业务跟踪id
     * @param <E>
     *            返回类型
     *
     * @return {@link Result}
     */
    public static <E> Result<E> build(ResultCode code, E data, String requestId) {
        return build(code.getCode(), code.getMessage(), data, requestId);
    }

    /**
     * 构造器
     *
     * @param code
     *            错误码
     * @param message
     *            错误描述
     * @param data
     *            返回的数据
     * @param requestId
     *            业务跟踪id
     * @param <E>
     *            返回类型
     *
     * @return {@link Result}
     */
    public static <E> Result<E> build(Integer code, String message, E data, String requestId) {
        Result<E> result = null;
        IMessage<E> messageResult = Message.build(ResultCode.success.getCode().equals(code), message, data, code,
                requestId);
        if (messageResult instanceof Result) {
            result = (Result<E>) messageResult;
        }
        return result;
    }

    @Override
    public <E> Result<E> build(boolean success, String message, E data, Object... params) {
        if (ObjectUtil.isEmpty(params) || params.length < 2) {
            throw new RuntimeException("需要两个参数, 第一个是code, 第二个是requestId");
        }
        Result<E> result = new Result<>();
        // 取第前两个, 第一个为 code , 第二个为requestId
        result.setCode((Integer) params[0]);
        result.setRequestId(params[1] + "");
        result.setSuccess(success);
        result.setMessage(message);
        result.setData(data);
        return result;
    }

    public static <T> Result<T> build(Integer code, String msg, T data) {
        Result<T> result = new Result<>();
        result.setCode(code);
        result.setMessage(msg);
        result.setData(data);
        LogDetail logDetail = LogDetail.get();
        result.setRequestId(logDetail.getRequsetId());
        return result;
    }

    public static <T> Result<T> build(CodeEnum resultEnum, T data) {
        Result<T> result = new Result<>();
        result.setCode(resultEnum.getCode());
        result.setMessage(resultEnum.getMessage());
        result.setData(data);
        LogDetail logDetail = LogDetail.get();
        result.setRequestId(logDetail.getRequsetId());
        return result;
    }

    public static <T> Result<T> buildError(String msg) {
        log.info("{}", msg);
        Result<T> result = new Result<>();
        result.setCode(CodeEnum.FAIL.getCode());
        result.setMessage(msg);
        result.setData(null);
        LogDetail logDetail = LogDetail.get();
        result.setRequestId(logDetail.getRequsetId());
        return result;
    }

    public static <T> Result<T> buildSuccess(T data) {
        Result<T> result = new Result<>();
        result.setCode(CodeEnum.SUCCESS.getCode());
        result.setMessage(CodeEnum.SUCCESS.getMessage());
        result.setData(data);
        LogDetail logDetail = LogDetail.get();
        result.setRequestId(logDetail.getRequsetId());
        return result;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getRequestId() {
        return requestId;
    }

    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }

    @Override
    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}
